package goutils

import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"reflect"
	"sort"
	"strings"
)

// 对参数进行加密
func SubMd5Params(params string, private string, indexStart, indexEnd int) string {
	hash := md5.New()
	hash.Write([]byte(params))
	var md5Str = hex.EncodeToString(hash.Sum([]byte(private)))
	substr := md5Str[indexStart:indexEnd]
	return substr

}

// 对参数进行加密
func EncryptMd5Params(params string, private string) string {
	hash := md5.New()
	hash.Write([]byte(params))
	return hex.EncodeToString(hash.Sum([]byte(private)))
}

// 对参数进行排序并拼接成字符串
func SortAndConcatParams(params map[string][]string, excludeField []string) string {
	var keys []string
	if params == nil {
		return ""
	}
	for k := range params {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	var sortedParams []string
	for _, k := range keys {
		//如果排除某字段时，跳过循环
		if Contains(excludeField, k) {
			continue
		}
		var paramValue = strings.Join(params[k], ",")
		sortedParams = append(sortedParams, fmt.Sprintf("%s=%s", k, paramValue))
	}
	return strings.Join(sortedParams, "&")
}

// 将结构体转换为TreeMap
func SortAndConcatJson(jsonBean any, excludeField []string) string {
	resultMap := make(map[string]interface{})
	var sortedKey []string

	entity := reflect.ValueOf(jsonBean).Elem().Interface()

	// 获取结构体字段和值，并存储到TreeMap中
	objValue := reflect.ValueOf(entity)
	objType := reflect.TypeOf(entity)
	if objType.Kind() == reflect.Struct {
		count := objValue.NumField()
		for i := 0; i < count; i++ {
			field := objType.Field(i)
			value := objValue.Field(i)

			// 如果字段是结构体类型，则递归转换为子map
			if value.Kind() == reflect.Struct {
				subMapStr := SortAndConcatJson(value.Interface(), excludeField)
				resultMap[field.Name] = subMapStr
				sortedKey = append(sortedKey, field.Name)
			} else {
				resultMap[field.Name] = value.Interface()
				sortedKey = append(sortedKey, field.Name)
			}
		}
	}

	sort.Strings(sortedKey)
	var sortedParams []string
	for _, k := range sortedKey {
		//如果排除某字段时，跳过循环
		if Contains(excludeField, k) {
			continue
		}
		var paramValue = resultMap[k]
		sortedParams = append(sortedParams, fmt.Sprintf("%s=%s", k, paramValue))
	}
	return strings.Join(sortedParams, "&")

}
